package com.gitee.feizns.ding.talk.zzd;

import com.alibaba.xxpt.gateway.shared.api.request.OapiGettokenJsonRequest;
import com.alibaba.xxpt.gateway.shared.client.http.IntelligentGetClient;
import com.alibaba.xxpt.gateway.shared.client.http.api.OapiSpResultContent;
import com.gitee.feizns.quickstart.jackson.Val;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;

/**
 * 企业内部应用accessToken
 *
 * /v1.0/oauth2/accessToken
 *
 * @link 钉钉文档链接 -> <a href="https://open.dingtalk.com/document/orgapp-server/obtain-the-access_token-of-an-internal-app">获取企业内部应用的accessToken</a>
 * @author feizns
 * @since 2023/09/12
 */
@RequiredArgsConstructor
public class AccessToken {

    /**
     * 配置信息
     */
    private final ZzdUtils utils;

    /**
     * access_token过期时间
     */
    private long expiredTime;

    /**
     * 缓存的access_token
     */
    private String accessToken;

    /**
     * 是否是已过期或空
     * @return boolean
     */
    public boolean isExpiredOrNull() {
        return accessToken == null || expiredTime <= System.currentTimeMillis();
    }

    /**
     * 获取token
     * @link 钉钉文档链接 -> <a href="https://open.dingtalk.com/document/orgapp-server/obtain-the-access_token-of-an-internal-app">获取企业内部应用的accessToken</a>
     * @apiNote 新版Api
     * @return access_token
     */
    @SneakyThrows
    public String get() {
        if ( isExpiredOrNull() ) {
            synchronized (this) {
                if ( isExpiredOrNull() ) {
                    //executableClient保证单例
                    IntelligentGetClient intelligentGetClient = utils.getClient().newIntelligentGetClient("/gettoken.json");
                    OapiGettokenJsonRequest oapiGettokenJsonRequest = new OapiGettokenJsonRequest();
                    //应用的唯一标识key
                    oapiGettokenJsonRequest.setAppkey(utils.getConfig().getAccessKey());
                    //应用的密钥
                    oapiGettokenJsonRequest.setAppsecret(utils.getConfig().getSecretKey());
                    //获取结果
                    OapiSpResultContent content = Utils.getContentIfFailThrow(intelligentGetClient.get(oapiGettokenJsonRequest));
                    Val data = Val.of(content).get("data");
                    String accessToken = data.get("accessToken").textValue();
                    int expiresIn = data.get("expiresIn").intValue();
                    this.expiredTime = System.currentTimeMillis() + expiresIn;
                    this.accessToken = accessToken;
                }
            }
        }
        return accessToken;
    }

}